package com.exam.utils;

import com.exam.entity.User;
import com.exam.exception.BusinessException;
import com.exam.exception.CommonErrorCode;
import com.exam.vo.CommonResult;
import com.exam.vo.TokenVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

public class JwtUtils {

    //token 过期时间 24h
    public static final long EXPIRE=1000*60*60*24;

    //密钥
    public static final  String APP_SECRET="saseessrtkookppijhfewewsadhuutresxvhjkk";

    // 生成token字符串的方法
    public static String createToken(User user){

        // 指定了 token 类型为 JWT，并且指定了加密算法为 HS256
        return Jwts.builder().setHeaderParam("type","JWT").setHeaderParam("alg","HS256")

                // 设置 JWT 的主题为 "police-user"
                .setSubject("police-user")
                // 设置 JWT 的签发时间为当前时间
                .setIssuedAt(new Date())
                // 设置 JWT 的过期时间为当前时间加上一个常量值 EXPIRE 所代表的时间间隔
                .setExpiration(new Date(System.currentTimeMillis()+EXPIRE))

                // 将用户的角色 ID、用户名和密码作为自定义声明（claim）添加到 JWT 的 payload 中
                .claim("roleId",user.getRoleId())
                .claim("username",user.getUsername())
                .claim("password",user.getPassword())

                // 使用指定的算法（HS256）和密钥（APP_SECRET）对 JWT 进行签名
                .signWith(SignatureAlgorithm.HS256,APP_SECRET)
                // 将 JWT 构建为最终的紧凑格式，即字符串表示形式。
                .compact();
    }

    /**
     * 根据token字符串获取用户
     */
    public static TokenVo getUserInfoByToken(HttpServletRequest request) {
        // 从请求头中获取token字符串
        String jwtToken=request.getHeader("authorization");
        // 如果token为空，则抛出未授权异常
        if (StringUtils.isEmpty(jwtToken)){
            throw new BusinessException(CommonErrorCode.UNAUTHORIZED);
        }
        // 解析token字符串，获取Claims对象
        Jws<Claims> claimsJws;
        try {
            claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        }catch (Exception e){
            // 如果解析token失败，则抛出自定义业务异常
            throw  new BusinessException(CommonErrorCode.E_200001);
        }
        // 从Claims对象中获取用户信息
        Claims claims=claimsJws.getBody();
        // 构建TokenVo对象并返回
        return TokenVo.builder()
                .roleId(claims.get("roleId",Integer.class))
                .username(claims.get("username",String.class))
                .password(claims.get("password",String.class))
                .build();
    }
}
